#include "http_download.h"

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <rtthread.h>
#include <finsh.h>

#include "webclient.h"

#define DBG_ENABLE
#define DBG_SECTION_NAME          "http_ota"
#ifdef OTA_DOWNLOADER_DEBUG
#define DBG_LEVEL                 DBG_LOG
#else
#define DBG_LEVEL                 DBG_INFO
#endif
#define DBG_COLOR
#include <rtdbg.h>


#define HTTP_OTA_BUFF_LEN         200
#define GET_HEADER_BUFSZ          1024
#define GET_RESP_BUFSZ            512
#define HTTP_OTA_DL_DELAY         (10 * RT_TICK_PER_SECOND)

#define HTTP_OTA_URL              "http://192.168.1.104/image/amp.img"

/* the address offset of download partition */
int begin_offset ;
static int file_size = 0;
uint8_t ota_downdata[250*1024];
static void print_progress(size_t cur_size, size_t total_size)
{
    static unsigned char progress_sign[100 + 1];
    uint8_t i, per = cur_size * 100 / total_size;

    if (per > 100)
    {
        per = 100;
    }

    for (i = 0; i < 100; i++)
    {
        if (i < per)
        {
            progress_sign[i] = '=';
        }
        else if (per == i)
        {
            progress_sign[i] = '>';
        }
        else
        {
            progress_sign[i] = ' ';
        }
    }

    progress_sign[sizeof(progress_sign) - 1] = '\0';

    LOG_I("Download: [%s] %03d%%\033[1A", progress_sign, per);
}


static int http_ota_print_context(char *buffer, int length)
{
    int outindex, inindex = 0;
    int boundary;

    /* print the receive data */
    for (outindex = 0; outindex < length; outindex = outindex + inindex)
    {
        char print_buffer[HTTP_OTA_BUFF_LEN + 1] = {0};
        char *point = RT_NULL;
        point = print_buffer;

        if(length - outindex > HTTP_OTA_BUFF_LEN)
        {
            boundary = HTTP_OTA_BUFF_LEN;
        }
        else
        {
            boundary = length - outindex;
        }

        for (inindex = 0; inindex < boundary; inindex++)
        {
            *point++ = buffer[outindex + inindex];
            //存储
            ota_downdata[begin_offset++]=buffer[outindex + inindex];
        }
        *point = 0;
        rt_kprintf("%04d - %04d: %s\n", outindex, outindex + boundary - 1, print_buffer);
    }

    /* release this buffer if we have handled data */
    web_free(buffer);

    return RT_EOK;
}

int http_download_ota(const char* uri)
{
    int ret = RT_EOK;
    struct webclient_session* session = RT_NULL;
    //初始化部分参数
    begin_offset = 0;
    rt_memset(ota_downdata,0,sizeof(ota_downdata));
    /* create webclient session and set header response size */
    session = webclient_session_create(GET_HEADER_BUFSZ);
    if (!session)
    {
        LOG_E("open uri failed.");
        ret = -RT_ERROR;
        goto __exit;
    }

    /* get the real data length */
    webclient_shard_head_function(session, uri, &file_size);

    if (file_size == 0)
    {
        LOG_E("Request file size is 0!");
        ret = -RT_ERROR;
        goto __exit;
    }
    else if (file_size < 0)
    {
        LOG_E("webclient GET request type is chunked.");
        ret = -RT_ERROR;
        goto __exit;
    }
    LOG_I("OTA file size is (%d)", file_size);
    LOG_I("\033[1A");

    webclient_register_shard_position_function(session, http_ota_print_context);
    /* the "memory size" that you can provide in the project and uri */
    ret = webclient_shard_position_function(session, uri, 0, file_size, HTTP_OTA_BUFF_LEN);

    /* clear the handle function */
    webclient_register_shard_position_function(session, RT_NULL);

    if (ret == RT_EOK)
    {
        if (session != RT_NULL)
        {
            webclient_close(session);
            session = RT_NULL;
        }

        LOG_I("\033[0B");
        LOG_I("Download firmware to flash success.");
        //LOG_I("System now will restart...");

        rt_thread_delay(rt_tick_from_millisecond(5));

        /* Reset the device, Start new firmware */
    //    extern void rt_hw_cpu_reset(void);
      //  rt_hw_cpu_reset();
    }
    else
    {
        LOG_E("Download firmware failed.");
    }

__exit:
    if (session != RT_NULL)
        webclient_close(session);
    //begin_offset = 0;

    return ret;
}

void http_ota_2(uint8_t argc, char **argv)
{
    if (argc < 2)
    {
        rt_kprintf("using uri: " HTTP_OTA_URL "\n");
        http_download_ota(HTTP_OTA_URL);
    }
    else
    {
        http_download_ota(argv[1]);
    }
}
/**
 * msh />http_ota [url]
*/
MSH_CMD_EXPORT(http_ota_2, Use HTTP to download the firmware);
 /* PKG_USING_HTTP_OTA */
